/*
 * Copyright 2021-2022 Open Kunlun Technology <https://www.openkunlun.io>
 */

package io.openkunlun.scalarpc.codegen.model

import scala.meta._

/**
 * @author kostas.kougios
 *         Date: 29/08/17
 */
case class TraitEx private (meta: TraitEx.Meta) extends CodeEx
  with MethodEx.Contains[TraitEx]
  with MetaEx.Contains
  with MetaEx.ContainsMods[TraitEx]
  with MetaEx.ContainsTypeParams[TraitEx]
  with CodeEx.Name[TraitEx]
  with TemplateEx.Contains[TraitEx]
  with Extending[TraitEx] {

  override def tree: Defn.Trait = Defn.Trait(meta.mods.toList, meta.tname, meta.tparams.toList, Ctor.Primary(Nil, Name(""), Nil), meta.template)
  override def name: String = meta.tname.value
  override def withName(name: String): TraitEx = copy(meta.copy(tname = scala.meta.Type.Name(name)))
  override def withTypeParams(params: Seq[TypeParamEx]): TraitEx = copy(meta = meta.copy(tparams = params.map(_.meta.param).toList))
  override def withMods(mods: ModsEx): TraitEx = copy(meta = meta.copy(mods = mods.meta.mods.toList))
  override protected def withTemplate(t: Template): TraitEx = copy(meta.copy(template = t))
}

object TraitEx extends PartialParser[TraitEx] {

  case class Meta(
    mods: Seq[Mod],
    tname: scala.meta.Type.Name,
    tparams: Seq[scala.meta.Type.Param],
    template: Template
  ) extends MetaEx with MetaEx.Template with MetaEx.TypeParams with MetaEx.Mods

  override def parser: PartialFunction[Tree, TraitEx] = {
    case q"..$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
      TraitEx(Meta(mods, tpname, tparams, Template(earlydefns.toList, parents.toList, self, stats.toList)))
  }
}
